package com.example.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.Result;
import com.example.entity.SSku;
import com.example.service.SSkuService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/sku")
@Slf4j
public class SkuController {

    @Autowired
    private SSkuService skuService;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    private ObjectMapper objectMapper;

    public SkuController() {
        // 调用初始化方法
        initializeObjectMapper();
    }

    private void initializeObjectMapper() {
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule()); // 支持Java 8日期时间类型
        // 在这里添加任何其他必要的ObjectMapper配置
    }


    @ApiOperation("后台新增商品子项")
    @PostMapping
    public Result<?> certainSave(@RequestBody SSku sku) {
        //数据库存sku
        skuService.save(sku);
        // 获取新增SKU的spu_id
        Long spuId = sku.getSpuId();

        // 构建需要删除的Redis键的key
        String key = "spu:" + spuId + ":skuList";

        // 从Redis中删除对应的键
        redisTemplate.delete(key);
        return Result.success();
    }


    @ApiOperation("根据id批量删除sku商品")
    @DeleteMapping
    public Result<?> deleteSku(@RequestBody List<Long> skuIdList) {
        // 数据库中逻辑删除sku（如果需要）
        skuService.removeBatchByIds(skuIdList);

        // 创建一个集合来存储所有不同的spuId
        Set<Long> spuIdSet = new HashSet<>();

        // 遍历skuIdList，为每个skuId获取对应的spuId，并添加到spuIdSet中
        for (Long skuId : skuIdList) {
            Long spuId = getSpuIdBySkuId(skuId);
            if (spuId != null) {
                spuIdSet.add(spuId);
            }
        }

        // 遍历spu_id集合，构建Redis键并删除
        for (Long spuId : spuIdSet) {
            String key = "spu:" + spuId + ":skuList";
            redisTemplate.delete(key);
        }

        return Result.success("删除成功");
    }

    @ApiOperation("根据id批量下架sku商品")
    @PostMapping("/takeOffSku")
    public Result<?> takeOffSku(@RequestBody List<Long> skuIdList) {
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SSku::getId,skuIdList);
        SSku sSku = new SSku();
        sSku.setState(1);
        skuService.update(sSku,wrapper);
        // 创建一个集合来存储所有不同的spuId
        Set<Long> spuIdSet = new HashSet<>();

        // 遍历skuIdList，为每个skuId获取对应的spuId，并添加到spuIdSet中
        for (Long skuId : skuIdList) {
            Long spuId = getSpuIdBySkuId(skuId);
            if (spuId != null) {
                spuIdSet.add(spuId);
            }
        }

        // 遍历spu_id集合，构建Redis键并删除
        for (Long spuId : spuIdSet) {
            String key = "spu:" + spuId + ":skuList";
            redisTemplate.delete(key);
        }

        return Result.success();
    }

    @ApiOperation("根据id批量上架sku商品")
    @PostMapping("/takeOnSku")
    public Result<?> takeOnSku(@RequestBody List<Long> skuIdList) {
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SSku::getId,skuIdList);
        SSku sSku = new SSku();
        sSku.setState(0);
        skuService.update(sSku,wrapper);
        // 创建一个集合来存储所有不同的spuId
        Set<Long> spuIdSet = new HashSet<>();

        // 遍历skuIdList，为每个skuId获取对应的spuId，并添加到spuIdSet中
        for (Long skuId : skuIdList) {
            Long spuId = getSpuIdBySkuId(skuId);
            if (spuId != null) {
                spuIdSet.add(spuId);
            }
        }

        // 遍历spu_id集合，构建Redis键并删除
        for (Long spuId : spuIdSet) {
            String key = "spu:" + spuId + ":skuList";
            redisTemplate.delete(key);
        }
        return Result.success();
    }

    @ApiOperation("根据spu_id批量下架sku")
    @PostMapping("/takeOffSpu")
    public Result<?> takeOffSpu(@RequestBody List<Long> list){
        //数据库下架
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SSku::getSpuId,list);
        SSku sSku = new SSku();
        sSku.setState(1);
        skuService.update(sSku,wrapper);

        // 遍历spu_id集合，构建Redis键并删除
        for (Long spuId : list) {
            String key = "spu:" + spuId + ":skuList";
            redisTemplate.delete(key);
        }
        return Result.success();
    }

    @ApiOperation("根据spu_id批量上架sku")
    @PostMapping("/takeOnSpu")
    public Result<?> takeOnSpu(@RequestBody List<Long> list){
        //数据库下架
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SSku::getSpuId,list);
        SSku sSku = new SSku();
        sSku.setState(0);
        skuService.update(sSku,wrapper);

        // 遍历spu_id集合，构建Redis键并删除
        for (Long spuId : list) {
            String key = "spu:" + spuId + ":skuList";
            redisTemplate.delete(key);
        }

        return Result.success();
    }

    @ApiOperation("根据Id更新sku")
    @PutMapping
    public Result<?> updateSku(@RequestBody SSku sku){
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SSku::getId,sku.getId());
        skuService.update(sku,wrapper);

        // 获取新增SKU的spu_id
        Long spuId = sku.getSpuId();

        // 构建需要删除的Redis键的key
        String key = "spu:" + spuId + ":skuList";

        // 从Redis中删除对应的键
        redisTemplate.delete(key);
        return Result.success();
    }



    @ApiOperation("后台根据Spu_id获取对应sku所有商品")
    @GetMapping("/back")
    public Result<List<SSku>> backfindSku(@RequestParam Long id) {
        String key = "spu:" + id + ":skuList";
        List<String> serializedSkus;

        // 检查Redis中是否存在数据
        serializedSkus = redisTemplate.opsForList().range(key, 0, -1).stream().map(Object::toString) // 对每个元素调用toString方法
                .collect(Collectors.toList());
        if (serializedSkus.isEmpty()) {
            // 如果Redis中没有数据，则从MySQL获取数据
            LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SSku::getSpuId,id);
            List<SSku> skuList = skuService.list(wrapper);
            if (skuList != null && !skuList.isEmpty()) {
                // 将数据序列化并存入Redis
                for (SSku sku : skuList) {
                    String serializedSku = serializeSku(sku);
                    redisTemplate.opsForList().rightPush(key, serializedSku);
                }
                // 再次获取序列化后的列表
                serializedSkus = redisTemplate.opsForList().range(key, 0, -1).stream().map(Object::toString) // 对每个元素调用toString方法
                        .collect(Collectors.toList());
            }
        }

        // 反序列化并返回结果
        List<SSku> getSkus = serializedSkus.stream()
                .map(serializedSku -> deserializeSku(serializedSku))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return Result.success(getSkus);
    }

    private String serializeSku(SSku sku) {
        try {
            return objectMapper.writeValueAsString(sku);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }

    private SSku deserializeSku(String serializedSku) {
        try {
            return objectMapper.readValue(serializedSku, SSku.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }


    @ApiOperation("前台根据Spu_id获取对应sku所有商品")
    @GetMapping("/front")
    public Result<List<SSku>> preFindSku(@RequestParam Long id) {
        String key = "spu:" + id + ":skuList";
        List<String> serializedSkus;

        // 检查Redis中是否存在数据
        serializedSkus = redisTemplate.opsForList().range(key, 0, -1).stream().map(Object::toString) // 对每个元素调用toString方法
                .collect(Collectors.toList());
        if (serializedSkus.isEmpty()) {
            // 如果Redis中没有数据，则从MySQL获取数据
            LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SSku::getSpuId,id);
            List<SSku> skuList = skuService.list(wrapper);
            if (skuList != null && !skuList.isEmpty()) {
                // 将数据序列化并存入Redis
                for (SSku sku : skuList) {
                    String serializedSku = serializeSku(sku);
                    redisTemplate.opsForList().rightPush(key, serializedSku);
                }
                // 再次获取序列化后的列表
                serializedSkus = redisTemplate.opsForList().range(key, 0, -1).stream().map(Object::toString) // 对每个元素调用toString方法
                        .collect(Collectors.toList());
            }
        }

        // 过滤state为0的SKU并返回结果
        List<SSku> getSkus = serializedSkus.stream()
                .map(serializedSku -> deserializeSku(serializedSku))
                .filter(sku -> sku != null && sku.getState() == 0)
                .collect(Collectors.toList());

        return Result.success(getSkus);
    }


    // 根据skuId找到对应的spuId
    private Long getSpuIdBySkuId(Long skuId) {
        // 实现逻辑来找到spuId
        Long spuId = skuService.findSpuId(skuId);
        // 这可能涉及到查询数据库或其他业务逻辑
        return spuId;
    }


}
